//
// RTSPMessage.h
//
// $Id: //base/include/RTSPMessage.h
//
// Library: base
// Package: RTSP
// Module : RTSPMessage
// Author :	Jelin,doitsjz@163.com
// Date	  :	10/30/2012
// 
// Definition of the RTSPMessage class.
//
// Copyright (c) 2012-2012, iGuard.
//


#ifndef RTSPMESSAGE_INCLUDED
#define RTSPMESSAGE_INCLUDED

/**
	RTSPMessage for class
*/
/*
	  method            direction        object     requirement
      DESCRIBE          C->S             P,S        recommended
      ANNOUNCE          C->S, S->C       P,S        optional
      GET_PARAMETER     C->S, S->C       P,S        optional
      OPTIONS           C->S, S->C       P,S        required
                                                    (S->C: optional)
      PAUSE             C->S             P,S        recommended
      PLAY              C->S             P,S        required
      RECORD            C->S             P,S        optional
      REDIRECT          S->C             P,S        optional
      SETUP             C->S             S          required
      SET_PARAMETER     C->S, S->C       P,S        optional
      TEARDOWN          C->S             P,S        required
*/

/*
	general-header     =     Cache-Control   ; Section 12.8
                         |     Connection        ; Section 12.10
                         |     Date              ; Section 12.18
                         |     Via               ; Section 12.43

*/
/*	 entity-header       =    Allow               ; Section 12.4
                         |    Content-Base        ; Section 12.11
                         |    Content-Encoding    ; Section 12.12
                         |    Content-Language    ; Section 12.13
                         |    Content-Length      ; Section 12.14
                         |    Content-Location    ; Section 12.15
                         |    Content-Type        ; Section 12.16
                         |    Expires             ; Section 12.19
                         |    Last-Modified       ; Section 12.24
                         |    extension-header
*/
/*
Header               type   support   methods
   Accept               R      opt.      entity
   Accept-Encoding      R      opt.      entity
   Accept-Language      R      opt.      all
   Allow                r      opt.      all
   Authorization        R      opt.      all
   Bandwidth            R      opt.      all
   Blocksize            R      opt.      all but OPTIONS, TEARDOWN
   Cache-Control        g      opt.      SETUP
   Conference           R      opt.      SETUP
   Connection           g      req.      all
   Content-Base         e      opt.      entity
   Content-Encoding     e      req.      SET_PARAMETER
   Content-Encoding     e      req.      DESCRIBE, ANNOUNCE
   Content-Language     e      req.      DESCRIBE, ANNOUNCE
   Content-Length       e      req.      SET_PARAMETER, ANNOUNCE
   Content-Length       e      req.      entity
   Content-Location     e      opt.      entity
   Content-Type         e      req.      SET_PARAMETER, ANNOUNCE
   Content-Type         r      req.      entity
   CSeq                 g      req.      all
   Date                 g      opt.      all
   Expires              e      opt.      DESCRIBE, ANNOUNCE
   From                 R      opt.      all
   If-Modified-Since    R      opt.      DESCRIBE, SETUP
   Last-Modified        e      opt.      entity
   Proxy-Authenticate
   Proxy-Require        R      req.      all
   Public               r      opt.      all
   Range                R      opt.      PLAY, PAUSE, RECORD
   Range                r      opt.      PLAY, PAUSE, RECORD
   Referer              R      opt.      all
   Require              R      req.      all
   Retry-After          r      opt.      all
   RTP-Info             r      req.      PLAY
   Scale                Rr     opt.      PLAY, RECORD
   Session              Rr     req.      all but SETUP, OPTIONS
   Server               r      opt.      all
   Speed                Rr     opt.      PLAY
   Transport            Rr     req.      SETUP
   Unsupported          r      req.      all
   User-Agent           R      opt.      all
   Via                  g      opt.      all
   WWW-Authenticate     r      opt.      all

*/
#include "base.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/Net/MediaType.h"

using Poco::Net::MessageHeader; 
using Poco::Net::MediaType;

class CRtspTransport;
class CRange;
class BASE_API RTSPMessage:public MessageHeader
{
public:
	void setVersion(const std::string& version);
	const std::string& getVersion() const;
	void setDate(const std::string& date);
	void setDate();
	const std::string& getDate() const;

	void setCSeq(int cseq);
	const int getCSeq() const;

	void setUserAgent(const std::string& userAgent);
	void setUserAgent();

	void setAccept(const std::string& mediaType);
	void setAccept();
	const std::string& getAccept() const;

	void setTransport(const std::string& transport);
	void setTransport(const CRtspTransport& transport);
	void getTransport(std::string& transport);
	void getTransport(CRtspTransport& transport);

	void setRange(const std::string& range);
	void setRange(const CRange& range);
	//just consider Session ID ,not include <timeout> attritue
	void setSession(const std::string& session);
	const std::string& getSession() const;

	void setContentLength(std::streamsize length);
	std::streamsize getContentLength() const;
	void setContentType(const std::string& mediaType);
	const std::string& getContentType() const;

	void setContentBody(const std::string& body);
	const std::string& getContentBody() const;
//	void setContentBody(CSdp& sdp);

	void setMessage(const std::string& message);
	void getMessage(std::string& message);


	static const std::string RTSP_1_0;
	static const std::string RTSP_2_0;
	static const std::string Accept;
	static const std::string CSeq;
	static const std::string UserAgent;
	static const std::string Transport;
	static const std::string Session;
	static const std::string Range;
	
	static const std::string AcceptEncoding;
	static const std::string AcceptLanguage;
	static const std::string Authorization;
	static const std::string Bandwidth;
	static const std::string Blocksize;
	static const std::string CacheControl;
	static const std::string Conference;
	static const std::string Connection;
	static const std::string ContentBase;
	static const std::string ContentEncoding;
	static const std::string ContentLanguage;
	static const std::string ContentLength;
	static const std::string ContentLocation;
	static const std::string ContentType;
	static const std::string Date;
	static const std::string Expires;
	static const std::string From;
	static const std::string Host;
	static const std::string IfMatch;
	static const std::string IfModifiedSince;
	static const std::string LastModified;
	static const std::string Location;
	static const std::string ProxyAuthenticate;
	static const std::string ProxyRequire;
	static const std::string Referer;
	static const std::string RetryAfter;
	static const std::string Require;
	static const std::string RTPInfo;
	static const std::string Scale;
	static const std::string Speed;
	static const std::string Timestamp;
	static const std::string Vary;
	static const std::string Via;
	static const std::string Allow;
	static const std::string Public;
	static const std::string Server;
	static const std::string Unsupported;
	static const std::string WWWAuthenticate;

	static const std::string IDENTITY_TRANSFER_ENCODING;
	static const std::string CHUNKED_TRANSFER_ENCODING;

	static const int         UNKNOWN_CONTENT_LENGTH;
	static const std::string UNKNOWN_CONTENT_TYPE;
	
	static const std::string CONTENT_LENGTH;
	static const std::string CONTENT_TYPE;
	static const std::string TRANSFER_ENCODING;
	static const std::string CONNECTION;
	
	static const std::string CONNECTION_KEEP_ALIVE;
	static const std::string CONNECTION_CLOSE;

	static const std::string EMPTY;

	static const std::string APP_SDP_TYPE;
	static const std::string TXT_PARA_TYPE;

protected:
	RTSPMessage();
	RTSPMessage(const std::string& version);
	virtual ~RTSPMessage();
	std::string _body;
private:
	RTSPMessage(const RTSPMessage&);
	RTSPMessage& operator = (const RTSPMessage&);
	
	std::string _version;
};


//
// inlines
//
inline const std::string& RTSPMessage::getVersion() const
{
	return _version;
}

class MultiValue : public MessageHeader
{
protected:
	MultiValue(){};
	~MultiValue(){};
public:
	virtual void write(std::ostream& ostr) const;
	virtual void read(std::istream& istr);

private:
	MultiValue(const MultiValue&);
	MultiValue& operator = (const MultiValue&);
	enum Limits
		/// Limits for basic sanity checks when reading a header
	{
		MAX_NAME_LENGTH  = 256,
		MAX_VALUE_LENGTH = 4096
	};
};

class BASE_API CRtspTransport: public MultiValue
{
public:
	enum TP
	{
		RTP_AVP_UDP=0,
		RTP_AVP_TCP,		
		RTP_AVP_RUDP
	};
	CRtspTransport(int tpType=RTP_AVP_UDP);
	~CRtspTransport();
	void setInterleaved(int channel=0);
	void setClientPort(int port);
	void setServerPort(int port);
	void setMode(const std::string& mode);
	void setTTL(int ttl);
	void setDestination(const std::string& address);
	void setSSRC(const std::string& ssrc);

	virtual void write(std::ostream& ostr) const;
	virtual void read(std::istream& istr);
private:
	//RTP:RTP/AVP;TCP:RTP/AVP/TCP;
	std::string strTPType;
	//unicast,multicast
	std::string strTType;
private:
	CRtspTransport(const CRtspTransport&);
	CRtspTransport& operator = (const CRtspTransport&);
private:
	static const std::string DESTINATION;
	static const std::string INTERLEAVED;
	static const std::string CLIENT_PORT;
	static const std::string SERVER_PORT;
	static const std::string TTL;
	static const std::string SSRC;
	static const std::string MODE;
};
class BASE_API CRange: public MultiValue
{
/*	Range            = "Range" ":" 1\#ranges-specifier
                          [ ";" "time" "=" utc-time ]
   ranges-specifier = npt-range | utc-range | smpte-range
*/
public:
	enum RS
	{
		NTP_RANGE = 0,
		UTC_RANGE = 1,		
		SMPTE_RANGE=2
	};
	CRange(int nType=NTP_RANGE);
	~CRange();
	void seRange(std::string& strStart,std::string& strEnd);
	void seRange(float fStart=0.00f,float fEnd=0.00f);
	void setTime(std::string& strTime);

private:
	CRange(const CRange&);
	CRange& operator = (const CRange&);
private:
	static const std::string SMPTE;
	static const std::string NPT;
	static const std::string CLOCK;
	static const std::string TIME;
};


#endif